/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package db.HivDbIntegration;

import humanNetwork.Edge;
import humanNetwork.HumanPPINetwork;
import humanNetwork.Node;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import units.CellType;
import units.Gene;
import units.GeneLibrary;
import units.MonkeyType;
import utils.FileUtils;
import utils.Handle;

/**
 *
 * @author jamie
 */
public class MakeNetworkOutput_together {

    private File outputFolder = new File("/Users/jamie/Dropbox/monkeys/networks/mainNetworks/");
    private HumanPPINetwork hppin;
    private Handle handle;
    private List<String> symbols;
    private Map<String, List<String>> clusterMap;
    private int hivNodeId = -1;
    private Map<String, Node> hivNodes;
    private GeneLibrary library = new GeneLibrary();

    public MakeNetworkOutput_together() {
        library.populateGeneSymbols();
        makeNetwork();
    }

    private void makeNetwork() {

        hivNodeId = -1;
        handle = Handle.getConnectedHandle("monkeys");
        hppin = new HumanPPINetwork(HumanPPINetwork.ALL);
        setGeneSymbols();
        List<Edge> humanEdges = getHumanEdges(symbols);
        List<Edge> hivEdges = getHIVEdges(humanEdges);
        try {
            outputEdges(hivEdges, humanEdges);
            outputNodes();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        handle.closeConnection();
    }

    private void outputEdges(List<Edge> hivEdges, List<Edge> humanEdges) throws IOException {

        BufferedWriter writer = FileUtils.getBufferedWriter(new File(outputFolder, "edges_together.txt"));
        writer.append("id1\tid2\ttype\tinteractionType\n");
        for (Edge e : hivEdges) {
            writer.append(e.getNode1().getAnnot("symbol") + "\t" + e.getNode2().getAnnot("symbol") + "\thivEdge\t" + e.getAnnot("interactionType")+"\n");
        }
        for (Edge e : humanEdges) {
            writer.append(e.getNode1().getAnnot("symbol") + "\t" + e.getNode2().getAnnot("symbol") + "\thumanEdge\tnone\n");
        }
        writer.close();
    }

    private void setGeneSymbols() {
        String sql = "select distinct t3.gId, t2.clusterId, t4.symbol from clusterMembership t2, probeIdLookup t3, ncbi.gene_info t4 where t2.probeId=t3.probeId and t4.gId=t3.gId";
        ResultSet rs = handle.runSQLquery(sql);
        symbols = new ArrayList<String>();
        
        clusterMap = new HashMap<String, List<String>>();
        try {
            while (rs.next()) {

                int gId = rs.getInt("gId");
                String symbol = rs.getString("symbol");
                Gene g = library.getGene(gId);
                if (!symbols.contains(symbol)) {
                    symbols.add(symbol);
                }
                String clusterId = rs.getString("clusterId");
                if (!clusterMap.containsKey(clusterId)) {
                    clusterMap.put(clusterId, new ArrayList<String>());
                }
                clusterMap.get(clusterId).add(symbol);
                System.out.println(symbol);
            }
            rs.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        clusterMap.put("-1", new  ArrayList<String>());
        sql = "select distinct symbol from ncbi.gene_info t1, hiv_interactions.hiv_interactions t2 where t1.gId = t2.gId_2 order by symbol";
        rs = handle.runSQLquery(sql);
        try {
            while (rs.next()) {
                String symbol = rs.getString("symbol");
                if (!symbols.contains(symbol)) {
                    symbols.add(symbol);
                    clusterMap.get("-1").add(symbol);
                }

            }
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(MakeNetworkOutput_separate.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private List<Edge> getHumanEdges(List<String> symbols) {
        List<Edge> edges = new ArrayList<Edge>();
        for (Edge e : hppin.getEdges()) {
            String symbol1 = Gene.getGeneSymbol(e.getNode1().getId(), handle);
            String symbol2 = Gene.getGeneSymbol(e.getNode2().getId(), handle);
            e.getNode1().addAnnot("symbol", symbol1);
            e.getNode2().addAnnot("symbol", symbol2);
            if (symbols.contains(symbol1) && symbols.contains(symbol2) && !symbol1.equals("unknown") && !symbol2.equals("unknown")) {
                edges.add(e);
            }
        }
        return edges;
    }

    private List<Edge> getHIVEdges(List<Edge> humanEdges) {
        List<Edge> edges = new ArrayList<Edge>();
        hivNodes = new TreeMap<String, Node>();
        for (Edge humEdge : humanEdges) {
            List<Edge> edges1 = getHivEdge(hivNodes, humEdge.getNode1());
            List<Edge> edges2 = getHivEdge(hivNodes, humEdge.getNode2());
            for (Edge e : edges1) {
                int index = edges.indexOf(e);
                if (index < 0) {
                    edges.add(e);
                } else {
                    edges.get(index).addAnnot("interactionType", "multiple");
                }
            }
            for (Edge e : edges2) {
                int index = edges.indexOf(e);
                if (index < 0) {
                    edges.add(e);
                } else {
                    edges.get(index).addAnnot("interactionType", "multiple");
                }
            }
        }
        return edges;
    }

    private List<Edge> getHivEdge(Map<String, Node> hivNodes, Node humanNode) {
        List<Edge> hivEdges = new ArrayList<Edge>();
        String sql = "select distinct name_1, interaction from hiv_interactions.hiv_interactions where gId_2=" + humanNode.getId();
        ResultSet rs = handle.runSQLquery(sql);
        try {
            while (rs.next()) {
                Node hivNode;
                String hivProt = rs.getString("name_1");
                if (!hivNodes.containsKey(hivProt)) {
                    hivNode = new Node(hivNodeId);
                    hivNodeId--;
                    hivNode.addAnnot("symbol", hivProt);
                    hivNodes.put(hivProt, hivNode);
                } else {
                    hivNode = hivNodes.get(hivProt);
                }
                Edge hivEdge = new Edge(hivNode, humanNode);
                int index = hivEdges.indexOf(hivEdge);
                if (index < 0) {
                    hivEdge.addAnnot("interactionType", rs.getString("interaction"));
                    hivEdges.add(hivEdge);
                } else {
                    hivEdges.get(index).addAnnot("interactionType", "multiple");
                }
            }
            rs.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return hivEdges;
    }

    private void outputNodes() throws IOException {
        BufferedWriter writer = FileUtils.getBufferedWriter(new File(outputFolder, "nodes_together.txt"));
        writer.append("id\tcluster\torganism\n");
        for (String clusterId : clusterMap.keySet()) {
            for (String id : clusterMap.get(clusterId)) {
                writer.append(id + "\t" + clusterId + "\thuman\n");
            }
        }
        for (String hivProt : hivNodes.keySet()) {
            writer.append(hivProt + "\t-2\thiv\n");
        }
        writer.close();
    }

}
